package com.ktjy.order.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ktjy.base.Q;
import com.ktjy.base.R;
import com.ktjy.order.service.OrderService;
import com.ktjy.pojo.order.Order;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 订单接口
 *
 * @author LILIBO
 * @since 2023-02-18
 */
@Tag(name = "订单接口", description = "订单接口")
@RestController
@RequestMapping("/order")
public class OrderController {

    @Resource
    private OrderService orderService;

    /**
     * 新增订单记录
     *
     * @param order 订单
     * @return R 成功返回true
     */
    @Operation(summary = "新增订单记录")
    @PostMapping("/add")
    public R add(@Parameter(description = "订单对象") @RequestBody Order order) {
        return R.success(orderService.save(order));
    }

    /**
     * 保存或更新订单记录
     *
     * @param order 订单（带主键ID表示更新，否则为新增）
     * @return R 成功返回保存后的完整对象
     */
    @Operation(summary = "保存或更新订单记录")
    @PostMapping("/save")
    public R save(@Parameter(description = "订单对象") @RequestBody Order order) {
        return orderService.saveOrUpdate(order) ? R.success(order) : R.failure();
    }

    /**
     * 修改订单记录
     *
     * @param order 订单
     * @return R 成功返回true
     */
    @Operation(summary = "修改订单记录")
    @PostMapping("/update")
    public R update(@Parameter(description = "订单对象") @RequestBody Order order) {
        return R.success(orderService.updateById(order));
    }

    /**
     * 通过id删除一条订单记录
     *
     * @param id
     * @return R 成功返回true
     */
    @Operation(summary = "通过id删除一条订单记录")
    @PostMapping("/delete")
    public R deleteById(@Parameter(description = "订单id") Long id) {
        return R.success(orderService.removeById(id));
    }

    /**
     * 通过多个id批量删除订单记录
     *
     * @param ids
     * @return R
     */
    @Operation(summary = "通过多个id批量删除订单记录")
    @PostMapping("/remove")
    public R removeByIds(@Parameter(description = "订单id集合") @RequestBody List<Long> ids) {
        return R.success(orderService.removeByIds(ids));
    }

    /**
     * 通过id查询单条订单记录
     *
     * @param id
     * @return R
     */
    @Operation(summary = "通过id查询单条订单记录")
    @GetMapping("/{id}")
    public R getById(@Parameter(description = "订单id") @PathVariable Long id) {
        return R.success(orderService.getById(id));
    }

    /**
     * 查询订单列表
     * [Sentinel] 在Sentinel控制台中，对'/order/list'接口配置流控规则，流控模式选择'关联'模式，关联资源选择'/order/seckill'，流控阈值QPS为1，流控效果选择'快速失败'
     * 表示当'/order/seckill'访问量过大，接口的QPS超过1时，'/order/list'接口的QPS也会受到影响，达到流控效果
     * 注意：设置 sentinel.web-context-unify=false #不统一上下文
     *
     * @param order 订单
     * @return R
     */
    @Operation(summary = "查询订单列表")
    @GetMapping("/list")
    public R list(@Parameter(description = "查询的订单对象") Order order) {
        return R.success(orderService.list(order));
    }

    /**
     * 分页查询订单
     *
     * @param pageNo 当前页
     * @param pageSize 每页条数
     * @param order 订单
     * @return
     */
    @Operation(summary = "分页查询订单")
    @GetMapping("/page")
    public R page(@Parameter(description = "当前页") @RequestParam(required = false, defaultValue = "1") Long pageNo, @Parameter(description = "每页条数") @RequestParam(required = false, defaultValue = "10") Long pageSize, @Parameter(description = "查询的订单对象") Order order) {
        return R.success(orderService.page(new Page<>(pageNo, pageSize), order));
    }

    /**
     * 分页查询订单列表
     *
     * @param pageNo 当前页
     * @param pageSize 每页条数
     * @param param 通用查询参数
     * @return 返回分页数据列表，其中count为数据总量
     */
    @Operation(summary = "分页查询订单列表")
    @GetMapping("/querypage")
    public R queryPage(@Parameter(description = "当前页") @RequestParam(required = false, defaultValue = "1") Long pageNo, @Parameter(description = "每页条数") @RequestParam(required = false, defaultValue = "10") Long pageSize, @Parameter(description = "通用查询参数") Q param) {
        IPage<Order> page = orderService.queryPage(new Page<>(pageNo, pageSize), param);
        return R.success(page.getTotal(), page.getRecords());
    }

    /**
     * 创建订单
     *
     * @param productId 购买的商品ID
     * @param uid 购买用户ID
     * @return R 订单对象
     */
    @Operation(summary = "创建订单")
    @PostMapping("/create")
    public R create(@Parameter(description = "购买的商品ID") @RequestParam Long productId, @Parameter(description = "下单用户") @RequestParam Long uid) {
        return R.success(orderService.createOrder(productId, uid));
    }

    /**
     * 创建秒杀订单
     * [Sentinel] 在Sentinel控制台中，对'createOrder'资源配置流控规则，流控模式选择'链路'，入口资源选择'/order/seckill'，流控阈值QPS为1，流控效果选择'快速失败'
     * 表示当访问'/order/seckill'接口时，'createOrder'资源的QPS超过1时，才会进行流控，而访问'/order/create'接口时，'createOrder'资源的QPS超过1不会受到影响
     * 注意：设置 sentinel.web-context-unify=false #不统一上下文
     *
     * @param productId 购买的商品ID
     * @param uid 购买用户ID
     * @return R 订单对象
     */
    @Operation(summary = "创建秒杀订单")
    @PostMapping("/seckill")
    public R seckill(@Parameter(description = "购买的商品ID") @RequestParam Long productId, @Parameter(description = "下单用户") @RequestParam Long uid) {
        return R.success(orderService.createOrder(productId, uid));
    }

    /**
     * 测试订单写操作
     * [Sentinel] 在Sentinel控制台中，对'/order/read'接口配置流控规则，流控模式选择'关联'模式，关联资源选择'/order/write'，流控阈值QPS为1，流控效果选择'快速失败'
     * 表示当'/order/write'访问量过大，接口的QPS超过1时，'/order/read'接口的QPS也会受到影响，达到流控效果（优先保障'/order/write'）
     * 注意：设置 sentinel.web-context-unify=false #不统一上下文
     */
    @Operation(summary = "测试订单写操作")
    @GetMapping("/write")
    public R write() {
        return R.success(1, "测试订单写操作");
    }

    /**
     * 测试订单读操作
     * [Sentinel] 在Sentinel控制台中，对'/order/read'接口配置流控规则，流控模式选择'关联'模式，关联资源选择'/order/write'，流控阈值QPS为1，流控效果选择'快速失败'
     * 表示当'/order/write'访问量过大，接口的QPS超过1时，'/order/read'接口的QPS也会受到影响，达到流控效果（优先保障'/order/write'）
     * 注意：设置 sentinel.web-context-unify=false #不统一上下文
     *
     * @return
     */
    @Operation(summary = "测试订单读操作")
    @GetMapping("/read")
    public R read() {
        return R.success(1, "测试订单读操作");
    }

}
